package engine.material;

import java.util.Arrays;

import engine.shader.Shader;

public class Material {
	public static final Material RED = new Material(new float[]{1, 0, 0, 1});
	public static final Material GREEN = new Material(new float[]{0, 1, 0, 1});
	public static final Material BLUE = new Material(new float[]{0, 0, 1, 1});
	public static final Material YELLOW = new Material(new float[]{1, 1, 0, 1});
	public static final Material BLACK = new Material(new float[]{0, 0, 0, 1});
	public static final Material WHITE = new Material(new float[]{1, 1, 1, 1});
	public static final Material GRAY = new Material(new float[]{0.5f, 0.5f, 0.5f, 1});
	
	private float[] ambient;
	private float[] diffuse;
	private float[] specular;
	private float[] emission;
	private float shininess;

	public Material(float[] ambient, float[] diffuse, float[] specular,
			float[] emission, float shininess) {
		if(ambient == null || ambient.length < 4) {
			this.ambient = new float[] { 0, 0, 0, 1 };
		} else {
			this.ambient = ambient;
		}

		if(diffuse == null || diffuse.length < 4) {
			this.diffuse = new float[] { 0, 0, 0, 1 };
		} else {
			this.diffuse = diffuse;
		}

		if(specular == null || specular.length < 4) {
			this.specular = new float[] { 0, 0, 0, 1 };
		} else {
			this.specular = specular;
		}

		if(emission == null || emission.length < 4) {
			this.emission = new float[] { 0, 0, 0, 1 };
		} else {
			this.emission = emission;
		}
		
		this.shininess = shininess;
	}
	
	public Material(float[] ambientAndDiffuse) {
		this(ambientAndDiffuse, Arrays.copyOf(ambientAndDiffuse, 4), null, null, 0);
	}

	public Material copy() {
		Material copy = new Material(Arrays.copyOf(ambient, 4), Arrays.copyOf(diffuse, 4), Arrays.copyOf(specular, 4), Arrays.copyOf(emission, 4), shininess);

		return copy;
	}

	public void apply(Shader shader) {
		shader.sendUniform4f("material.ambient", ambient);
		shader.sendUniform4f("material.diffuse", diffuse);
		shader.sendUniform4f("material.specular", specular);
		shader.sendUniform4f("material.emissive", emission);
		shader.sendUniform1f("material.shininess", shininess);
	}

	public float[] getAmbient() {
		return ambient;
	}
	
	public void setAmbient(float r, float g, float b, float a) {
		ambient[0] = r;
		ambient[1] = g;
		ambient[2] = b;
		ambient[3] = a;
	}
	
	public void setAmbient(float[] ambient) {
		setAmbient(ambient[0], ambient[1], ambient[2], ambient[3]);
	}
	
	public float[] getDiffuse() {
		return diffuse;
	}
	
	public void setDiffuse(float r, float g, float b, float a) {
		diffuse[0] = r;
		diffuse[1] = g;
		diffuse[2] = b;
		diffuse[3] = a;
	}
	
	public void setDiffuse(float[] diffuse) {
		setDiffuse(diffuse[0], diffuse[1], diffuse[2], diffuse[3]);
	}
	
	public float[] getSpecular() {
		return specular;
	}
	
	public void setSpecular(float r, float g, float b, float a) {
		specular[0] = r;
		specular[1] = g;
		specular[2] = b;
		specular[3] = a;
	}
	
	public void setSpecular(float[] specular) {
		setSpecular(specular[0], specular[1], specular[2], specular[3]);
	}
	
	public float[] getEmission() {
		return emission;
	}
	
	public void setEmission(float r, float g, float b, float a) {
		emission[0] = r;
		emission[1] = g;
		emission[2] = b;
		emission[3] = a;
	}
	
	public void setEmission(float[] emission) {
		setEmission(emission[0], emission[1], emission[2], emission[3]);
	}
	
	public float getShininess() {
		return shininess;
	}
	
	public void setShininess(float shininess) {
		this.shininess = shininess;
	}
}
